﻿#include "tcpclient.h"
#include <mainwindow.h>

TcpClient* TcpClient::Instance=0;
extern intListener recfl;
extern QString recvvalue;
QString allerror;
extern intListener infochan;
// 指令结构体
struct order
{
    // 可以添加一个函数来序列化结构体
    QByteArray toByteArray(QString header,QString type,QString len,QString data,QString cd,QString tail) const {
        QString all = header+type+len+data+cd+tail;
        QByteArray byteArray;
        for(int i = 0;i<all.size();i++)
        {
            if(all[i]==' ')
                continue;   //跳过
            int num  = all.mid(i,2).toUInt(nullptr,16);
            i++;
            byteArray.append(num);
        }
        return byteArray;
    }
};
TcpClient* TcpClient::getInstance()
{
    if(Instance==0)
        Instance =new TcpClient();
    return Instance;
}

TcpClient::TcpClient(QObject *parent): QTcpSocket(parent)
{
    mapGZ = new QMap<QString, QString>();
    mapGZ->insert("0B","EEROM初始化错误");
    mapGZ->insert("0C","温度采集初始化失败");
    mapGZ->insert("0D","温度读取失败");
    mapGZ->insert("0E","A区温度过高");
    mapGZ->insert("0F","B区温度过高");
    mapGZ->insert("10","C区温度过高");
    mapGZ->insert("11","D区温度过高");
    mapGZ->insert("12","E区温度过高");
    mapGZ->insert("13","F区温度过高");
    mapGZ->insert("14","A区温度异常");
    mapGZ->insert("15","B区温度异常");
    mapGZ->insert("16","C区温度异常");
    mapGZ->insert("17","D区温度异常");
    mapGZ->insert("18","E区温度异常");
    mapGZ->insert("19","F区温度异常");
    mapGZ->insert("1A","水泵故障");
    mapGZ->insert("1B","风扇故障");
    mapGZ->insert("1C","仓门打开");
    mapGZ->insert("1D","ad模块通信异常");

    //自动连接在信号发射时被识别为队列连接/信号在主线程发射
    connect(this, &TcpClient::SignalConnectToHost, this, [&](const QString & address, quint16 port) {
        this->abort();
        this->connectToHost(QHostAddress(address), port, QIODevice::ReadWrite);
        if(this->waitForConnected(3000)){
            MainWindow::tcpStatus.set(0);
        }else {
            MainWindow::tcpStatus.set(1);
        }
    }, Qt::AutoConnection);

    //连接了TCP服务端
    QObject::connect(this, &QAbstractSocket::connected, this, [&]() {
        MainWindow::tcpStatus.set(0);
        m_bOnLine = true;
        QTimer::singleShot(30000, this, SLOT(onTimeout()));
    }, Qt::DirectConnection);

    //断开了TCP服务端
    QObject::connect(this, &QAbstractSocket::disconnected, this, [&]() {
        MainWindow::tcpStatus.set(1);
        m_bOnLine = false;
    }, Qt::DirectConnection);

    //收到了TCP服务的数据
    QObject::connect(this, &QIODevice::readyRead, this, [&]() {
        logClient=loghelper::getInstance();
        QByteArray arr = this->readAll();
        QString str;
        for(int c :arr)
        {
            if(c>=0)
            {
                str += QString(" %1").arg(c, 2, 16, QChar('0')).toUpper();
            }
            else
            {
                str += QString(" %1").arg(c+256, 2, 16, QChar('0')).toUpper();
            }
        }
        str= str.simplified();
        logClient->WriteLog("CommLog","接收:\n"+str);
        QStringList list=str.split(" ");

        if(list.length()>12){
            recvvalue = str;
            recfl.set(1);

            if(list[2]=="00" && list[3]=="38"){
                if(list[10]=="00" && list[11]=="00"){
                    MainWindow::startExperimentStatus.set(0);
                }
                else if(list[10]=="00" &&list[11]=="01"){
                    MainWindow::startExperimentStatus.set(1);
                }
            }

            if( list[3]=="3D" && list[7]=="07"){
                if(list.length()>150)//荧光数据
                {
                    for(int i=12;i<list.length()-4;i+=10){
                        if(i+4>list.length()||i+5>list.length()||i+6>list.length()||i+7>list.length()||
                                i+8>list.length()||i+9>list.length()){
                            break;
                        }else {
                            QSqlDatabase db = dbHelper::openConnection();
                            QSqlQuery query(db);

                            QString sql=QString("Insert into FluorescenceData values('','%1','%2','%3',"
                                                "'%4','%5','%6','','','','')").arg(
                                        common->SixteenToTen(list[i]+" "+list[i+1]),
                                    common->SixteenToTen(list[9]),
                                    common->SixteenToTen(list[i+2]+" "+ list[i+3]),
                                    common->SixteenToTen(list[i+4]+" "+ list[i+5]),
                                    common->SixteenToTen(list[i+6]+" "+ list[i+7]),
                                    common->SixteenToTen(list[i+8]+" "+ list[i+9])
                                    );
                            query.exec(sql);
                        }
                    }


                    QSqlDatabase db = dbHelper::openConnection();
                    QSqlQuery query(db);
                    db.transaction();
                    QString sql=QString("update FluorescenceData set SampleId=(select id from sampleInfo s "
                                        "where "
                                        "case "
                                        "when FluorescenceData.PositionNumber %1 = 0 "
                                        "then s.RowNum=FluorescenceData.PositionNumber /4-1 and s.ColNum=3 "
                                        "else "
                                        "s.RowNum = FluorescenceData.PositionNumber /4 and s.ColNum = FluorescenceData.PositionNumber %1-1 "
                                        "end)").arg("%4");
                    query.exec(sql);

                    sql="DELETE FROM FluorescenceData WHERE rowid NOT IN (SELECT MIN(rowid) FROM FluorescenceData GROUP BY positionNumber, CyclesNumber)";
                    query.exec(sql);
                    db.commit();

                }
            }

            if(list[2]=="00" && list[3]=="3A")
            {
                if(list.length()==30 )//温度数据
                {
                    MainWindow::experimentStep.set(common->SixteenToTen(list[10]).toInt());
                    MainWindow::experimentCircle.set(common->SixteenToTen(list[11]).toInt());

                    MainWindow::tempDataOne = list[12]+" "+list[13];

                    QString tempTwo=common->SixteenToTen(list[14]+" "+list[15]);
                    MainWindow::tempDataTwo=tempTwo.toDouble()/100;

                    QString tempThree=common->SixteenToTen(list[16]+" "+list[17]);
                    MainWindow::tempDataThree=tempThree.toDouble()/100;

                    QString tempFour=common->SixteenToTen(list[18]+" "+list[19]);
                    MainWindow::tempDataFour=tempFour.toDouble()/100;

                    QString tempFive=common->SixteenToTen(list[20]+" "+list[21]);
                    MainWindow::tempDataFive=tempFive.toDouble()/100;

                    QString tempSix=common->SixteenToTen(list[22]+" "+list[23]);
                    MainWindow::tempDataSix=tempSix.toDouble()/100;

                    MainWindow::tempOrder = list[25].toInt();
                    MainWindow::canRefChart.set(1);
                }
                if(list.length()>150)//荧光数据
                {
                    for(int i=12;i<list.length()-4;i+=10){
                        if(i+4>list.length()||i+5>list.length()||i+6>list.length()||i+7>list.length()||
                                i+8>list.length()||i+9>list.length()){
                            break;
                        }else {
                            QSqlDatabase db = dbHelper::openConnection();
                            QSqlQuery query(db);

                            QString sql=QString("Insert into FluorescenceData values('','%1','%2','%3',"
                                                "'%4','%5','%6','','','','')").arg(
                                        common->SixteenToTen(list[i]+" "+list[i+1]),
                                    common->SixteenToTen(list[11]),
                                    common->SixteenToTen(list[i+2]+" "+ list[i+3]),
                                    common->SixteenToTen(list[i+4]+" "+ list[i+5]),
                                    common->SixteenToTen(list[i+6]+" "+ list[i+7]),
                                    common->SixteenToTen(list[i+8]+" "+ list[i+9])
                                    );
                            query.exec(sql);

                        }

                    }

                    QSqlDatabase db = dbHelper::openConnection();
                    QSqlQuery query(db);

                    db.transaction();
                    QString sql=QString("update FluorescenceData set SampleId=(select id from sampleInfo s "
                                        "where "
                                        "case "
                                        "when FluorescenceData.PositionNumber %1 = 0 "
                                        "then s.RowNum=FluorescenceData.PositionNumber /4-1 and s.ColNum=3 "
                                        "else "
                                        "s.RowNum = FluorescenceData.PositionNumber /4 and s.ColNum = FluorescenceData.PositionNumber %1-1 "
                                        "end)").arg("%4");
                    query.exec(sql);

                    sql="DELETE FROM FluorescenceData WHERE rowid NOT IN (SELECT MIN(rowid) FROM FluorescenceData GROUP BY positionNumber, CyclesNumber)";
                    query.exec(sql);

                    db.commit();
                    MainWindow::canRefChart.set(0);
                }
            }

        }
        // cnr 07发送 6.25
        //        QString Data=str.remove(QRegExp("\\s"));
        //        QString ty = Data.mid(4,4);
        //        QString wendubs = Data.mid(8,4);
        //        QString isright = Data.mid(12,4);
        //        QString isright2 = Data.mid(16,4);
        //        QString rw = Data.mid(50,2);
        //        if(ty=="003A"){
        //            QString gzfl = Data.mid(Data.length()-10,2);
        //            if (wendubs=="0018"&&rw=="07"&&Data.length()==60) {
        //                if(rw=="07"){
        //                    order order1;
        //                    this->write(order1.toByteArray("6200","003A","000A","000100010007","1652","55AA"));
        //                }
        //            }else if(gzfl=="07"){
        //                int flnum=0;
        //                for(int i=24;i<=Data.length()-14;i+=2){
        //                    QString gzdz = Data.mid(i,2);
        //                    QString gzdzv=mapGZ->value(gzdz);
        //                    if((flnum+1)%4==0){
        //                        allerror += gzdzv+"\n";
        //                    }else{
        //                        allerror += gzdzv+";";
        //                    }
        //                }
        //                MainWindow::experimentStatus.set(3);
        //                infochan.set(infochan.get()+1);
        //                allerror.clear();
        //            }
        //        }

    }, Qt::DirectConnection);

    //执行数据发送过程
    QObject::connect(this, &TcpClient::SignalSendingData, this, [&](const QByteArray c_btaData) {
        this->write(c_btaData);
    }, Qt::AutoConnection);
}

//
TcpClient::~TcpClient()
{
}

//跨线程转换
void TcpClient::ClientConnectToHost(const QString & address, quint16 port)
{
    emit SignalConnectToHost(address, port);
}

//跨线程转换
void TcpClient::ClientSendingData(const QByteArray & c_btaData)
{
    emit SignalSendingData(c_btaData);
}

//是否在线
bool TcpClient::IsOnline()
{
    return m_bOnLine;
}

void TcpClient::OpenDoor(){
    this->write("");
}

void TcpClient::onTimeout(){
    order order1;
    this->write(order1.toByteArray("6200","003A","000A","000100010005","0000","55AA"));
}
